"""
Copyright 2012 Wieser Dietmar, Margit Mutschlechner.

This file is part of Multimedia Social Networking Platform.

Multimedia Social Networking Platform is free software: 
you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Multimedia Social Networking Platform is distributed
in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Multimedia Social Networking Platform.  
If not, see <http://www.gnu.org/licenses/>.

"""

from threading import Timer
from msnp.service import network
from msnp.logger import Logger
from msnp.service.network.model.CustodyModel import CustodyQueueType
from msnp.persistence import PersistenceController
from msnp.service.network import CustodyQueue, BackupController
from msnp import model
from msnp.model.PTPModel import BackupContent
import time

#the timer instance
__llCrashTimer = None
#the timer interval (seconds)
__timerInterval = 10.0
#interval (seconds) in which a low level peer has to send a keep-alive. otherwise the responsible peer assumes its crash.
__crashThreshold = 200.0


#################
## START_TIMER ##
#################

def startLowLevelPeerCrashTimer():
    """This function starts the timer.
    """
    
    global __timerInterval
    global __llCrashTimer
    __llCrashTimer = Timer(__timerInterval, __checkLowLevelPeers)
    __llCrashTimer.start()
    
    
################
## STOP_TIMER ##
################

def stopLowLevelPeerCrashTimer():
    """This function stops the timer."""
    
    global __llCrashTimer
    print "stop llPeer crash timer"
    if __llCrashTimer != None:
        __llCrashTimer.cancel()
        
        
####################
## TIMER_FINISHED ##
####################

def __checkLowLevelPeers():
    """This method is executed during a run of the timer.
    
    It checks every low level peer for its last keep-alive and starts the timer again.
    If the last keep-alive is older than the crashThreshold allows, the low level peer is assumed to be crashed.
    The low level peer and all corresponding messages are removed."""
    
    global __crashThreshold
    for llPeerName, entry in network.NetworkController.getMySelf().getLowLevelPeers().items():
        timestamp = entry.getLastKeepAlive()
        currentTime = time.time()
        if currentTime - timestamp > __crashThreshold:
            Logger.info("remove low level peer " + llPeerName + " because of timeout ")
            #delete from low level peer list
            network.NetworkController.getMySelf().removeLowLevelPeer(llPeerName)
            messages = CustodyQueue.retrieveAndDelete(llPeerName, CustodyQueueType.ALL_TYPES)
            PersistenceController.insertMessages(llPeerName, messages)
            user = PersistenceController.selectUserImResponsibleForUsername(llPeerName)
            myName = network.NetworkController.getMySelf().getMyIdentity().getName()
            backupContent = BackupContent(myName, [user], None, None, model.PTPModel.BackupType.UPDATE)
            BackupController.updateBackupAtFingers(backupContent)
    startLowLevelPeerCrashTimer()

